package core.threadpool;

public abstract class PoolManager {
	
	private int maxSize;
	private int coreSize;
	private int currentPool;
	private boolean isReused = true;
	private long timeAlive = 0;
	private PoolQueue<PoolThread> threadQueue = new PoolQueue<>();
	private PoolQueue<Runnable> runQueue = new PoolQueue<>();
	
	public PoolManager(int coreSize, int maxSize, long timeAlive){
		this.coreSize = coreSize;
		this.maxSize = maxSize;
		this.timeAlive = timeAlive;
		for (int i = 0; i < coreSize; i++) {
			PoolThread poolThread = new PoolThread(threadQueue, runQueue, coreSize, timeAlive);
			threadQueue.addLast(poolThread);
			poolThread.start();
		}
	}
	

	public abstract void onReject(Runnable r);
	
	public void execute(Runnable r){
		int runSize = runQueue.size();
		
		if (runSize >= maxSize) {
			onReject(r);
			return;
		}
		
		runQueue.addLast(r);
		synchronized (runQueue) {
			runQueue.notifyAll();
		}
		
		if (runQueue.size() > 0 && threadQueue.size() < maxSize) {
			PoolThread poolThread = new PoolThread(threadQueue, runQueue, coreSize, timeAlive);
			poolThread.start();
			threadQueue.addLast(poolThread);
		}
	}
	
	public int getMaxSize(){
		return this.maxSize;
	}
	
	public void setMaxSize(int maxSize){
		this.maxSize = maxSize;
	}
	
	public int getCoreSize(){
		return this.coreSize;
	}
	
	public void setCoreSize(int coreSize){
		this.coreSize = coreSize;
	}
	
	public int getCurrentPool(){
		currentPool = threadQueue.size();
		return currentPool;
	}
	
	public int getCurrentTask(){
		return runQueue.size();
	}
	
}
